Package Dependencies/ Data

Load Packages

First I need to load up the packages I’ll need

library(sf)
library(ggplot2) #development version!
## devtools::install_github("tidyverse/ggplot2")
library(tidyverse)
library(readr)
library(cowplot)
library(sp)
library(gridExtra)
library(dplyr)
library(ggrepel)
library(plyr)

Import Postcode Data

Now I import my data. I filter for the Arran postcodes, (since Arran all begins ‘KA27’).

#Add download commands for data.
## Finding the Arran coordinates
arrancoordinates <- read.csv("../alldata/ukpostcodes.csv") %>%
 filter(substr(postcode,1,4)=="KA27")
#Find way to replace with existing SIMD shape files
arransubsect <- read_sf("../alldata/Scotland_pcs_2011") %>%
filter(substr(label,1,4)=="KA27")

Import SIMD data

Now I load the SIMD data, containing the geometries (shapefiles) and SIMD data (percentiles, etc)

reorderedvector<- c("S01011174", "S01011171", "S01011177", "S01011176", "S01011175", "S01011173", "S01011172" )
arran2016 <- read_sf("../alldata/SG_SIMD_2016")[c(4672,4666,4669,4671,4667,4668,4670),] %>%
  slice(match(reorderedvector, DataZone))
Arrandz2012 <- c(4409,4372,4353,4352,4351,4350,4349)
arran2012 <- read_sf("../alldata/SG_SIMD_2012")[Arrandz2012,]
arran2009 <- read_sf("../alldata/SG_SIMD_2009")[Arrandz2012,]
arran2006 <- read_sf("../alldata/SG_SIMD_2006")[Arrandz2012,]
arran2004 <- read_sf("../alldata/SG_SIMD_2004")[Arrandz2012,]
sharedvariables <- intersect(colnames(arran2016), colnames(arran2012)) %>%
  intersect(colnames(arran2009))  %>%
  intersect(colnames(arran2006))  %>%
  intersect(colnames(arran2004))
  
arran20162 <- arran2016 %>%
  select(sharedvariables) %>%
  mutate(year="2016")
arran20122 <- arran2012 %>%
  select(sharedvariables) %>%
  mutate(year="2012")
arran20092 <- arran2009 %>%
  select(sharedvariables) %>%
  mutate(year="2009")
arran20062 <- arran2006 %>%
  select(sharedvariables) %>%
  mutate(year="2006")
arran20042 <- arran2004 %>%
  select(sharedvariables) %>%
  mutate(year="2004")
arransimd <- rbind(arran20162,arran20122,arran20092,arran20062,arran20042) %>%
mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]])
    )
arransimd$listID <- revalue(arransimd$DataZone,
               c("S01004409"="S01004409/S01011174", "S01004372"="S01004372/S01011171", "S01004353"="S01004353/S01011177", "S01004352"="S01004352/S01011176", "S01004351"="S01004351/S01011175", "S01004350"="S01004350/S01011173", "S01004349"="S01004349/S01011172", "S01011174"="S01004409/S01011174", "S01011171"="S01004372/S01011171", "S01011177"="S01004353/S01011177", "S01011176"="S01004352/S01011176", "S01011175"="S01004351/S01011175", "S01011173"="S01004350/S01011173", "S01011172"="S01004349/S01011172"))

Now I want to overlay the postcodes by Datazone. To do this I’ve converted both the Arran coordinates and Arran (2016) shapefiles into spatial points/polygons, converted them into a common CRS, and then compared them by using ‘plyr::over()’. This gives me the object ‘namingdzpostcode’, with the postcode rows grouped into IDs (unidentified datazones).

simple.sf <- st_as_sf(arrancoordinates, coords=c('longitude','latitude'))
st_crs(simple.sf) <- 4326
exampleshapes <- sf:::as_Spatial(arran2016$geometry) %>%
  spTransform(CRS("+proj=longlat +datum=WGS84"))
examplepoints <- sf:::as_Spatial(simple.sf$geom) %>%
  spTransform(CRS("+proj=longlat +datum=WGS84"))
namingdzpostcode <- over(exampleshapes, examplepoints, returnList = TRUE)

I can then take a member reference from the orginal postcode list, which gives me a selection of the rows in that DZ. For simplicity I’ve written this as a new function. ##Mutate arrancoordinates to label the IDs

function100 <- function(argument) 
{
  argument <- arrancoordinates[namingdzpostcode[[argument]],] %>% mutate(DataZone=argument)
}
arrancoordinates <- lapply(1:7,function100)
arrancoordinates <- rbind(arrancoordinates[[1]], arrancoordinates[[2]], arrancoordinates[[3]], arrancoordinates[[4]], arrancoordinates[[5]], arrancoordinates[[6]], arrancoordinates[[7]])
arrancoordinates$listID <- revalue(as.character(arrancoordinates$DataZone),
               c('1'="S01004409/S01011174", '2'="S01004372/S01011171", '3'="S01004353/S01011177", '4'="S01004352/S01011176", '5'="S01004351/S01011175", '6'="S01004350/S01011173", '7'="S01004349/S01011172"))

Labelling the namingdzpostcode list

names(namingdzpostcode) <- c(unique(arransimd$listID))

///

Mapping

library(rgdal)
library(leaflet)
library(ggmap)

Coordinates

postcodelist <- paste(unique(arrancoordinates$listID), "Postcodes", sep=" ")
datazonelist <- paste(unique(arrancoordinates$listID), "Datazones", sep=" ")
m = leaflet() %>% addTiles() %>% setView(-5.227680, 55.582338, zoom = 10) 

Example Markers

Inputing example markers.

cliniccoordinates <- read.csv("../alldata/clinics.csv") %>%
dplyr::left_join(arrancoordinates, by="postcode")
Column `postcode` joining factors with different levels, coercing to character vector
#change to character
cliniccoordinates$X <- as.character(cliniccoordinates$X)

Map

Overlaying percentiles

exampleshapes2 <- as(arransimd, "Spatial") %>%
spTransform(CRS("+proj=longlat +datum=WGS84"))

Convert to function

functionmap <- function(argument, argument2) 
{
pal2 <- colorNumeric(palette = "viridis",
  domain = argument)
listlistlist <- paste(datazonelist, argument, sep=" ")
m %>% 
#alldatazones  
addPolygons(data=exampleshapes2[exampleshapes2$year == 2004, ], 
            weight = 2, 
            label = listlistlist[29:35],
            group = "2004",
            fillOpacity =0.8,
            color = ~pal2(argument[29:35]),
            highlightOptions = highlightOptions(color = "black", weight = 2,
      bringToFront = TRUE)) %>% 
hideGroup("2004") %>% 
  
addPolygons(data=exampleshapes2[exampleshapes2$year == 2006, ], 
            weight = 2, 
            label = listlistlist[22:28],
            group = "2006",
            fillOpacity =0.8,
            color = ~pal2(argument[22:28]),
            highlightOptions = highlightOptions(color = "black", weight = 2,
      bringToFront = TRUE)) %>% 
hideGroup("2006") %>% 
  
addPolygons(data=exampleshapes2[exampleshapes2$year == 2009, ], 
            weight = 2, 
            label = listlistlist[15:21],
            group = "2009",
            fillOpacity =0.8,
            color = ~pal2(argument[15:21]),
            highlightOptions = highlightOptions(color = "black", weight = 2,
      bringToFront = TRUE)) %>% 
hideGroup("2009") %>% 
  
addPolygons(data=exampleshapes2[exampleshapes2$year == 2012, ], 
            weight = 2, 
            label = listlistlist[8:14],
            group = "2012",
            fillOpacity =0.8,
            color = ~pal2(argument[8:14]),
            highlightOptions = highlightOptions(color = "black", weight = 2,
      bringToFront = TRUE)) %>% 
hideGroup("2012") %>% 
addPolygons(data=exampleshapes2[exampleshapes2$year == 2016, ], 
            weight = 2, 
            label = listlistlist[1:7],
            group = "2016",
            fillOpacity =0.8,
            color = ~pal2(argument[1:7]),
            highlightOptions = highlightOptions(color = "black", weight = 2,
      bringToFront = TRUE)) %>% 
hideGroup("2016") %>% 
  
#cliniccoordinates
addMarkers(
    lng = cliniccoordinates$longitude, lat = cliniccoordinates$latitude,
    label = cliniccoordinates$X,
    labelOptions = labelOptions(noHide = F), group = cliniccoordinates$X) %>%
  hideGroup(cliniccoordinates$X) %>%   
addLegend("bottomleft", pal = pal2, values = argument,
    title = argument2,
    opacity = 1
  )  %>%  
#Layers control
addLayersControl(
    baseGroups = c("2004", "2006", "2009", "2012", "2016", "Nothing"),
    overlayGroups = c(cliniccoordinates$X),
    options = layersControlOptions(collapsed = TRUE)
  )
}
colnames(arransimd)
 [1] "DataZone"   "LAName"     "Rank"       "Quintile"   "Decile"     "Vigintile"  "Percentile" "IncRate"   
 [9] "IncRank"    "EmpRate"    "EmpRank"    "HlthRank"   "EduRank"    "GAccRank"   "HouseRank"  "Shape_Leng"
[17] "Shape_Area" "year"       "geometry"   "lon"        "lat"        "listID"    
functionmap(exampleshapes2$Rank, "Rank")

functionmap(exampleshapes2$Quintile, "Quintile")

functionmap(exampleshapes2$Quintile, "Decile")

functionmap(exampleshapes2$Vigintile, "Vigintile")

functionmap(exampleshapes2$Percentile, "Percentile")

functionmap(exampleshapes2$IncRate, "IncRate")

functionmap(exampleshapes2$IncRank, "IncRank")

functionmap(exampleshapes2$EmpRate, "EmpRate")

functionmap(exampleshapes2$HlthRank, "HlthRank")

functionmap(exampleshapes2$EduRank, "EduRank")

functionmap(exampleshapes2$GAccRank, "GAccRank")

functionmap(exampleshapes2$HouseRank, "HouseRank")
LS0tCnRpdGxlOiAiTWFwNSBDb2RlIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgojUGFja2FnZSBEZXBlbmRlbmNpZXMvIERhdGEKIyNMb2FkIFBhY2thZ2VzCkZpcnN0IEkgbmVlZCB0byBsb2FkIHVwIHRoZSBwYWNrYWdlcyBJJ2xsIG5lZWQKYGBge3J9CmxpYnJhcnkoc2YpCmxpYnJhcnkoZ2dwbG90MikgI2RldmVsb3BtZW50IHZlcnNpb24hCiMjIGRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigidGlkeXZlcnNlL2dncGxvdDIiKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZWFkcikKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KHNwKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KHBseXIpCmBgYAoKIyNJbXBvcnQgUG9zdGNvZGUgRGF0YQpOb3cgSSBpbXBvcnQgbXkgZGF0YS4gSSBmaWx0ZXIgZm9yIHRoZSBBcnJhbiBwb3N0Y29kZXMsIChzaW5jZSBBcnJhbiBhbGwgYmVnaW5zICdLQTI3JykuCmBgYHtyfQojQWRkIGRvd25sb2FkIGNvbW1hbmRzIGZvciBkYXRhLgojIyBGaW5kaW5nIHRoZSBBcnJhbiBjb29yZGluYXRlcwphcnJhbmNvb3JkaW5hdGVzIDwtIHJlYWQuY3N2KCIuLi9hbGxkYXRhL3VrcG9zdGNvZGVzLmNzdiIpICU+JQogZmlsdGVyKHN1YnN0cihwb3N0Y29kZSwxLDQpPT0iS0EyNyIpCgojRmluZCB3YXkgdG8gcmVwbGFjZSB3aXRoIGV4aXN0aW5nIFNJTUQgc2hhcGUgZmlsZXMKYXJyYW5zdWJzZWN0IDwtIHJlYWRfc2YoIi4uL2FsbGRhdGEvU2NvdGxhbmRfcGNzXzIwMTEiKSAlPiUKZmlsdGVyKHN1YnN0cihsYWJlbCwxLDQpPT0iS0EyNyIpCmBgYAoKIyNJbXBvcnQgU0lNRCBkYXRhCk5vdyBJIGxvYWQgdGhlIFNJTUQgZGF0YSwgY29udGFpbmluZyB0aGUgZ2VvbWV0cmllcyAoc2hhcGVmaWxlcykgYW5kIFNJTUQgZGF0YSAocGVyY2VudGlsZXMsIGV0YykKYGBge3J9CnJlb3JkZXJlZHZlY3RvcjwtIGMoIlMwMTAxMTE3NCIsICJTMDEwMTExNzEiLCAiUzAxMDExMTc3IiwgIlMwMTAxMTE3NiIsICJTMDEwMTExNzUiLCAiUzAxMDExMTczIiwgIlMwMTAxMTE3MiIgKQoKYXJyYW4yMDE2IDwtIHJlYWRfc2YoIi4uL2FsbGRhdGEvU0dfU0lNRF8yMDE2IilbYyg0NjcyLDQ2NjYsNDY2OSw0NjcxLDQ2NjcsNDY2OCw0NjcwKSxdICU+JQogIHNsaWNlKG1hdGNoKHJlb3JkZXJlZHZlY3RvciwgRGF0YVpvbmUpKQoKQXJyYW5kejIwMTIgPC0gYyg0NDA5LDQzNzIsNDM1Myw0MzUyLDQzNTEsNDM1MCw0MzQ5KQoKYXJyYW4yMDEyIDwtIHJlYWRfc2YoIi4uL2FsbGRhdGEvU0dfU0lNRF8yMDEyIilbQXJyYW5kejIwMTIsXQphcnJhbjIwMDkgPC0gcmVhZF9zZigiLi4vYWxsZGF0YS9TR19TSU1EXzIwMDkiKVtBcnJhbmR6MjAxMixdCmFycmFuMjAwNiA8LSByZWFkX3NmKCIuLi9hbGxkYXRhL1NHX1NJTURfMjAwNiIpW0FycmFuZHoyMDEyLF0KYXJyYW4yMDA0IDwtIHJlYWRfc2YoIi4uL2FsbGRhdGEvU0dfU0lNRF8yMDA0IilbQXJyYW5kejIwMTIsXQoKc2hhcmVkdmFyaWFibGVzIDwtIGludGVyc2VjdChjb2xuYW1lcyhhcnJhbjIwMTYpLCBjb2xuYW1lcyhhcnJhbjIwMTIpKSAlPiUKICBpbnRlcnNlY3QoY29sbmFtZXMoYXJyYW4yMDA5KSkgICU+JQogIGludGVyc2VjdChjb2xuYW1lcyhhcnJhbjIwMDYpKSAgJT4lCiAgaW50ZXJzZWN0KGNvbG5hbWVzKGFycmFuMjAwNCkpCiAgCmFycmFuMjAxNjIgPC0gYXJyYW4yMDE2ICU+JQogIHNlbGVjdChzaGFyZWR2YXJpYWJsZXMpICU+JQogIG11dGF0ZSh5ZWFyPSIyMDE2IikKYXJyYW4yMDEyMiA8LSBhcnJhbjIwMTIgJT4lCiAgc2VsZWN0KHNoYXJlZHZhcmlhYmxlcykgJT4lCiAgbXV0YXRlKHllYXI9IjIwMTIiKQphcnJhbjIwMDkyIDwtIGFycmFuMjAwOSAlPiUKICBzZWxlY3Qoc2hhcmVkdmFyaWFibGVzKSAlPiUKICBtdXRhdGUoeWVhcj0iMjAwOSIpCmFycmFuMjAwNjIgPC0gYXJyYW4yMDA2ICU+JQogIHNlbGVjdChzaGFyZWR2YXJpYWJsZXMpICU+JQogIG11dGF0ZSh5ZWFyPSIyMDA2IikKYXJyYW4yMDA0MiA8LSBhcnJhbjIwMDQgJT4lCiAgc2VsZWN0KHNoYXJlZHZhcmlhYmxlcykgJT4lCiAgbXV0YXRlKHllYXI9IjIwMDQiKQoKYXJyYW5zaW1kIDwtIHJiaW5kKGFycmFuMjAxNjIsYXJyYW4yMDEyMixhcnJhbjIwMDkyLGFycmFuMjAwNjIsYXJyYW4yMDA0MikgJT4lCm11dGF0ZSgKICAgIGxvbiA9IG1hcF9kYmwoZ2VvbWV0cnksIH5zdF9jZW50cm9pZCgueClbWzFdXSksCiAgICBsYXQgPSBtYXBfZGJsKGdlb21ldHJ5LCB+c3RfY2VudHJvaWQoLngpW1syXV0pCiAgICApCgphcnJhbnNpbWQkbGlzdElEIDwtIHJldmFsdWUoYXJyYW5zaW1kJERhdGFab25lLAogICAgICAgICAgICAgICBjKCJTMDEwMDQ0MDkiPSJTMDEwMDQ0MDkvUzAxMDExMTc0IiwgIlMwMTAwNDM3MiI9IlMwMTAwNDM3Mi9TMDEwMTExNzEiLCAiUzAxMDA0MzUzIj0iUzAxMDA0MzUzL1MwMTAxMTE3NyIsICJTMDEwMDQzNTIiPSJTMDEwMDQzNTIvUzAxMDExMTc2IiwgIlMwMTAwNDM1MSI9IlMwMTAwNDM1MS9TMDEwMTExNzUiLCAiUzAxMDA0MzUwIj0iUzAxMDA0MzUwL1MwMTAxMTE3MyIsICJTMDEwMDQzNDkiPSJTMDEwMDQzNDkvUzAxMDExMTcyIiwgIlMwMTAxMTE3NCI9IlMwMTAwNDQwOS9TMDEwMTExNzQiLCAiUzAxMDExMTcxIj0iUzAxMDA0MzcyL1MwMTAxMTE3MSIsICJTMDEwMTExNzciPSJTMDEwMDQzNTMvUzAxMDExMTc3IiwgIlMwMTAxMTE3NiI9IlMwMTAwNDM1Mi9TMDEwMTExNzYiLCAiUzAxMDExMTc1Ij0iUzAxMDA0MzUxL1MwMTAxMTE3NSIsICJTMDEwMTExNzMiPSJTMDEwMDQzNTAvUzAxMDExMTczIiwgIlMwMTAxMTE3MiI9IlMwMTAwNDM0OS9TMDEwMTExNzIiKSkKYGBgCgpOb3cgSSB3YW50IHRvIG92ZXJsYXkgdGhlIHBvc3Rjb2RlcyBieSBEYXRhem9uZS4KVG8gZG8gdGhpcyBJJ3ZlIGNvbnZlcnRlZCBib3RoIHRoZSBBcnJhbiBjb29yZGluYXRlcyBhbmQgQXJyYW4gKDIwMTYpIHNoYXBlZmlsZXMgaW50byBzcGF0aWFsIHBvaW50cy9wb2x5Z29ucywgY29udmVydGVkIHRoZW0gaW50byBhIGNvbW1vbiBDUlMsIGFuZCB0aGVuIGNvbXBhcmVkIHRoZW0gYnkgdXNpbmcgJ3BseXI6Om92ZXIoKScuClRoaXMgZ2l2ZXMgbWUgdGhlIG9iamVjdCAnbmFtaW5nZHpwb3N0Y29kZScsIHdpdGggdGhlIHBvc3Rjb2RlIHJvd3MgZ3JvdXBlZCBpbnRvIElEcyAodW5pZGVudGlmaWVkIGRhdGF6b25lcykuCmBgYHtyfQpzaW1wbGUuc2YgPC0gc3RfYXNfc2YoYXJyYW5jb29yZGluYXRlcywgY29vcmRzPWMoJ2xvbmdpdHVkZScsJ2xhdGl0dWRlJykpCnN0X2NycyhzaW1wbGUuc2YpIDwtIDQzMjYKCmV4YW1wbGVzaGFwZXMgPC0gc2Y6Ojphc19TcGF0aWFsKGFycmFuMjAxNiRnZW9tZXRyeSkgJT4lCiAgc3BUcmFuc2Zvcm0oQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQoKZXhhbXBsZXBvaW50cyA8LSBzZjo6OmFzX1NwYXRpYWwoc2ltcGxlLnNmJGdlb20pICU+JQogIHNwVHJhbnNmb3JtKENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKSkKCm5hbWluZ2R6cG9zdGNvZGUgPC0gb3ZlcihleGFtcGxlc2hhcGVzLCBleGFtcGxlcG9pbnRzLCByZXR1cm5MaXN0ID0gVFJVRSkKYGBgCgpJIGNhbiB0aGVuIHRha2UgYSBtZW1iZXIgcmVmZXJlbmNlIGZyb20gdGhlIG9yZ2luYWwgcG9zdGNvZGUgbGlzdCwgd2hpY2ggZ2l2ZXMgbWUgYSBzZWxlY3Rpb24gb2YgdGhlIHJvd3MgaW4gdGhhdCBEWi4gRm9yIHNpbXBsaWNpdHkgSSd2ZSB3cml0dGVuIHRoaXMgYXMgYSBuZXcgZnVuY3Rpb24uIAojI011dGF0ZSBhcnJhbmNvb3JkaW5hdGVzIHRvIGxhYmVsIHRoZSBJRHMKYGBge3J9CmZ1bmN0aW9uMTAwIDwtIGZ1bmN0aW9uKGFyZ3VtZW50KSAKewogIGFyZ3VtZW50IDwtIGFycmFuY29vcmRpbmF0ZXNbbmFtaW5nZHpwb3N0Y29kZVtbYXJndW1lbnRdXSxdICU+JSBtdXRhdGUoRGF0YVpvbmU9YXJndW1lbnQpCn0KCmFycmFuY29vcmRpbmF0ZXMgPC0gbGFwcGx5KDE6NyxmdW5jdGlvbjEwMCkKYXJyYW5jb29yZGluYXRlcyA8LSByYmluZChhcnJhbmNvb3JkaW5hdGVzW1sxXV0sIGFycmFuY29vcmRpbmF0ZXNbWzJdXSwgYXJyYW5jb29yZGluYXRlc1tbM11dLCBhcnJhbmNvb3JkaW5hdGVzW1s0XV0sIGFycmFuY29vcmRpbmF0ZXNbWzVdXSwgYXJyYW5jb29yZGluYXRlc1tbNl1dLCBhcnJhbmNvb3JkaW5hdGVzW1s3XV0pCgphcnJhbmNvb3JkaW5hdGVzJGxpc3RJRCA8LSByZXZhbHVlKGFzLmNoYXJhY3RlcihhcnJhbmNvb3JkaW5hdGVzJERhdGFab25lKSwKICAgICAgICAgICAgICAgYygnMSc9IlMwMTAwNDQwOS9TMDEwMTExNzQiLCAnMic9IlMwMTAwNDM3Mi9TMDEwMTExNzEiLCAnMyc9IlMwMTAwNDM1My9TMDEwMTExNzciLCAnNCc9IlMwMTAwNDM1Mi9TMDEwMTExNzYiLCAnNSc9IlMwMTAwNDM1MS9TMDEwMTExNzUiLCAnNic9IlMwMTAwNDM1MC9TMDEwMTExNzMiLCAnNyc9IlMwMTAwNDM0OS9TMDEwMTExNzIiKSkKYGBgCgojI0xhYmVsbGluZyB0aGUgbmFtaW5nZHpwb3N0Y29kZSBsaXN0CmBgYHtyfQpuYW1lcyhuYW1pbmdkenBvc3Rjb2RlKSA8LSBjKHVuaXF1ZShhcnJhbnNpbWQkbGlzdElEKSkKYGBgCgovLy8KCiNNYXBwaW5nCmBgYHtyfQpsaWJyYXJ5KHJnZGFsKQpsaWJyYXJ5KGxlYWZsZXQpCmxpYnJhcnkoZ2dtYXApCmBgYAoKIyNDb29yZGluYXRlcwpgYGB7cn0KcG9zdGNvZGVsaXN0IDwtIHBhc3RlKHVuaXF1ZShhcnJhbmNvb3JkaW5hdGVzJGxpc3RJRCksICJQb3N0Y29kZXMiLCBzZXA9IiAiKQpkYXRhem9uZWxpc3QgPC0gcGFzdGUodW5pcXVlKGFycmFuY29vcmRpbmF0ZXMkbGlzdElEKSwgIkRhdGF6b25lcyIsIHNlcD0iICIpCgptID0gbGVhZmxldCgpICU+JSBhZGRUaWxlcygpICU+JSBzZXRWaWV3KC01LjIyNzY4MCwgNTUuNTgyMzM4LCB6b29tID0gMTApIApgYGAKCiNFeGFtcGxlIE1hcmtlcnMKSW5wdXRpbmcgZXhhbXBsZSBtYXJrZXJzLgpgYGB7cn0KY2xpbmljY29vcmRpbmF0ZXMgPC0gcmVhZC5jc3YoIi4uL2FsbGRhdGEvY2xpbmljcy5jc3YiKSAlPiUKZHBseXI6OmxlZnRfam9pbihhcnJhbmNvb3JkaW5hdGVzLCBieT0icG9zdGNvZGUiKQojY2hhbmdlIHRvIGNoYXJhY3RlcgpjbGluaWNjb29yZGluYXRlcyRYIDwtIGFzLmNoYXJhY3RlcihjbGluaWNjb29yZGluYXRlcyRYKQpgYGAKCiNNYXAKIyNPdmVybGF5aW5nIHBlcmNlbnRpbGVzCmBgYHtyfQpleGFtcGxlc2hhcGVzMiA8LSBhcyhhcnJhbnNpbWQsICJTcGF0aWFsIikgJT4lCnNwVHJhbnNmb3JtKENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKSkKYGBgCgojI0NvbnZlcnQgdG8gZnVuY3Rpb24KYGBge3J9CmZ1bmN0aW9ubWFwIDwtIGZ1bmN0aW9uKGFyZ3VtZW50LCBhcmd1bWVudDIpIAp7CnBhbDIgPC0gY29sb3JOdW1lcmljKHBhbGV0dGUgPSAidmlyaWRpcyIsCiAgZG9tYWluID0gYXJndW1lbnQpCgpsaXN0bGlzdGxpc3QgPC0gcGFzdGUoZGF0YXpvbmVsaXN0LCBhcmd1bWVudCwgc2VwPSIgIikKCm0gJT4lIAoKI2FsbGRhdGF6b25lcyAgCmFkZFBvbHlnb25zKGRhdGE9ZXhhbXBsZXNoYXBlczJbZXhhbXBsZXNoYXBlczIkeWVhciA9PSAyMDA0LCBdLCAKICAgICAgICAgICAgd2VpZ2h0ID0gMiwgCiAgICAgICAgICAgIGxhYmVsID0gbGlzdGxpc3RsaXN0WzI5OjM1XSwKICAgICAgICAgICAgZ3JvdXAgPSAiMjAwNCIsCiAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0wLjgsCiAgICAgICAgICAgIGNvbG9yID0gfnBhbDIoYXJndW1lbnRbMjk6MzVdKSwKICAgICAgICAgICAgaGlnaGxpZ2h0T3B0aW9ucyA9IGhpZ2hsaWdodE9wdGlvbnMoY29sb3IgPSAiYmxhY2siLCB3ZWlnaHQgPSAyLAogICAgICBicmluZ1RvRnJvbnQgPSBUUlVFKSkgJT4lIApoaWRlR3JvdXAoIjIwMDQiKSAlPiUgCiAgCmFkZFBvbHlnb25zKGRhdGE9ZXhhbXBsZXNoYXBlczJbZXhhbXBsZXNoYXBlczIkeWVhciA9PSAyMDA2LCBdLCAKICAgICAgICAgICAgd2VpZ2h0ID0gMiwgCiAgICAgICAgICAgIGxhYmVsID0gbGlzdGxpc3RsaXN0WzIyOjI4XSwKICAgICAgICAgICAgZ3JvdXAgPSAiMjAwNiIsCiAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0wLjgsCiAgICAgICAgICAgIGNvbG9yID0gfnBhbDIoYXJndW1lbnRbMjI6MjhdKSwKICAgICAgICAgICAgaGlnaGxpZ2h0T3B0aW9ucyA9IGhpZ2hsaWdodE9wdGlvbnMoY29sb3IgPSAiYmxhY2siLCB3ZWlnaHQgPSAyLAogICAgICBicmluZ1RvRnJvbnQgPSBUUlVFKSkgJT4lIApoaWRlR3JvdXAoIjIwMDYiKSAlPiUgCiAgCmFkZFBvbHlnb25zKGRhdGE9ZXhhbXBsZXNoYXBlczJbZXhhbXBsZXNoYXBlczIkeWVhciA9PSAyMDA5LCBdLCAKICAgICAgICAgICAgd2VpZ2h0ID0gMiwgCiAgICAgICAgICAgIGxhYmVsID0gbGlzdGxpc3RsaXN0WzE1OjIxXSwKICAgICAgICAgICAgZ3JvdXAgPSAiMjAwOSIsCiAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0wLjgsCiAgICAgICAgICAgIGNvbG9yID0gfnBhbDIoYXJndW1lbnRbMTU6MjFdKSwKICAgICAgICAgICAgaGlnaGxpZ2h0T3B0aW9ucyA9IGhpZ2hsaWdodE9wdGlvbnMoY29sb3IgPSAiYmxhY2siLCB3ZWlnaHQgPSAyLAogICAgICBicmluZ1RvRnJvbnQgPSBUUlVFKSkgJT4lIApoaWRlR3JvdXAoIjIwMDkiKSAlPiUgCiAgCmFkZFBvbHlnb25zKGRhdGE9ZXhhbXBsZXNoYXBlczJbZXhhbXBsZXNoYXBlczIkeWVhciA9PSAyMDEyLCBdLCAKICAgICAgICAgICAgd2VpZ2h0ID0gMiwgCiAgICAgICAgICAgIGxhYmVsID0gbGlzdGxpc3RsaXN0Wzg6MTRdLAogICAgICAgICAgICBncm91cCA9ICIyMDEyIiwKICAgICAgICAgICAgZmlsbE9wYWNpdHkgPTAuOCwKICAgICAgICAgICAgY29sb3IgPSB+cGFsMihhcmd1bWVudFs4OjE0XSksCiAgICAgICAgICAgIGhpZ2hsaWdodE9wdGlvbnMgPSBoaWdobGlnaHRPcHRpb25zKGNvbG9yID0gImJsYWNrIiwgd2VpZ2h0ID0gMiwKICAgICAgYnJpbmdUb0Zyb250ID0gVFJVRSkpICU+JSAKaGlkZUdyb3VwKCIyMDEyIikgJT4lIAoKYWRkUG9seWdvbnMoZGF0YT1leGFtcGxlc2hhcGVzMltleGFtcGxlc2hhcGVzMiR5ZWFyID09IDIwMTYsIF0sIAogICAgICAgICAgICB3ZWlnaHQgPSAyLCAKICAgICAgICAgICAgbGFiZWwgPSBsaXN0bGlzdGxpc3RbMTo3XSwKICAgICAgICAgICAgZ3JvdXAgPSAiMjAxNiIsCiAgICAgICAgICAgIGZpbGxPcGFjaXR5ID0wLjgsCiAgICAgICAgICAgIGNvbG9yID0gfnBhbDIoYXJndW1lbnRbMTo3XSksCiAgICAgICAgICAgIGhpZ2hsaWdodE9wdGlvbnMgPSBoaWdobGlnaHRPcHRpb25zKGNvbG9yID0gImJsYWNrIiwgd2VpZ2h0ID0gMiwKICAgICAgYnJpbmdUb0Zyb250ID0gVFJVRSkpICU+JSAKaGlkZUdyb3VwKCIyMDE2IikgJT4lIAogIAojY2xpbmljY29vcmRpbmF0ZXMKYWRkTWFya2VycygKICAgIGxuZyA9IGNsaW5pY2Nvb3JkaW5hdGVzJGxvbmdpdHVkZSwgbGF0ID0gY2xpbmljY29vcmRpbmF0ZXMkbGF0aXR1ZGUsCiAgICBsYWJlbCA9IGNsaW5pY2Nvb3JkaW5hdGVzJFgsCiAgICBsYWJlbE9wdGlvbnMgPSBsYWJlbE9wdGlvbnMobm9IaWRlID0gRiksIGdyb3VwID0gY2xpbmljY29vcmRpbmF0ZXMkWCkgJT4lCiAgaGlkZUdyb3VwKGNsaW5pY2Nvb3JkaW5hdGVzJFgpICU+JSAgIAoKYWRkTGVnZW5kKCJib3R0b21sZWZ0IiwgcGFsID0gcGFsMiwgdmFsdWVzID0gYXJndW1lbnQsCiAgICB0aXRsZSA9IGFyZ3VtZW50MiwKICAgIG9wYWNpdHkgPSAxCiAgKSAgJT4lICAKCiNMYXllcnMgY29udHJvbAphZGRMYXllcnNDb250cm9sKAogICAgYmFzZUdyb3VwcyA9IGMoIjIwMDQiLCAiMjAwNiIsICIyMDA5IiwgIjIwMTIiLCAiMjAxNiIsICJOb3RoaW5nIiksCiAgICBvdmVybGF5R3JvdXBzID0gYyhjbGluaWNjb29yZGluYXRlcyRYKSwKICAgIG9wdGlvbnMgPSBsYXllcnNDb250cm9sT3B0aW9ucyhjb2xsYXBzZWQgPSBUUlVFKQogICkKfQpgYGAKCmBgYHtyfQpjb2xuYW1lcyhhcnJhbnNpbWQpCmBgYAoKYGBge3J9CmZ1bmN0aW9ubWFwKGV4YW1wbGVzaGFwZXMyJFJhbmssICJSYW5rIikKZnVuY3Rpb25tYXAoZXhhbXBsZXNoYXBlczIkUXVpbnRpbGUsICJRdWludGlsZSIpCmZ1bmN0aW9ubWFwKGV4YW1wbGVzaGFwZXMyJFF1aW50aWxlLCAiRGVjaWxlIikKZnVuY3Rpb25tYXAoZXhhbXBsZXNoYXBlczIkVmlnaW50aWxlLCAiVmlnaW50aWxlIikKZnVuY3Rpb25tYXAoZXhhbXBsZXNoYXBlczIkUGVyY2VudGlsZSwgIlBlcmNlbnRpbGUiKQpmdW5jdGlvbm1hcChleGFtcGxlc2hhcGVzMiRJbmNSYXRlLCAiSW5jUmF0ZSIpCmZ1bmN0aW9ubWFwKGV4YW1wbGVzaGFwZXMyJEluY1JhbmssICJJbmNSYW5rIikKZnVuY3Rpb25tYXAoZXhhbXBsZXNoYXBlczIkRW1wUmF0ZSwgIkVtcFJhdGUiKQpmdW5jdGlvbm1hcChleGFtcGxlc2hhcGVzMiRIbHRoUmFuaywgIkhsdGhSYW5rIikKZnVuY3Rpb25tYXAoZXhhbXBsZXNoYXBlczIkRWR1UmFuaywgIkVkdVJhbmsiKQpmdW5jdGlvbm1hcChleGFtcGxlc2hhcGVzMiRHQWNjUmFuaywgIkdBY2NSYW5rIikKZnVuY3Rpb25tYXAoZXhhbXBsZXNoYXBlczIkSG91c2VSYW5rLCAiSG91c2VSYW5rIikKYGBgCgo=